#ifndef __WIZ_DATATYPE_SIGNAL_TEMPLATE_HPP__SHANHAOBO_19800429__
#define __WIZ_DATATYPE_SIGNAL_TEMPLATE_HPP__SHANHAOBO_19800429__

#include "../../Base/WizBase.hpp"
#include "../../Core/Container/WizDataTypeSet.hpp"

namespace Wiz
{
    namespace Signal
    {
        template<class ParamT> class Type;
    } /// end of namespace Signal
} /// end of namespace Wiz

#endif /*__WIZ_DATATYPE_SIGNAL_TEMPLATE_HPP__SHANHAOBO_19800429__*/

#undef  WIZ_SIGNAL_PARAM_COUNT
#define WIZ_SIGNAL_PARAM_COUNT  WIZ_MPP_REPEAT_FILE_COUNT
#if defined(WIZ_SIGNAL_PARAM_COUNT) && (WIZ_SIGNAL_PARAM_COUNT >= 0) && (WIZ_SIGNAL_PARAM_COUNT < 255)

namespace Wiz
{
    namespace Signal
    {
        template<class RetT WIZ_COMMA_IF(WIZ_SIGNAL_PARAM_COUNT) WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, class T)>
        class Type<RetT(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, T))>
        {
            WIZ_DECLARE_CLASS_THIS(Type);
            typedef RetT                                                                        tRet;
            typedef ::Wiz::Function::Type<tRet(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, T))>    tFunction;
            typedef ::Wiz::Set::Type<tFunction>                                                 tContainer;
            typedef tRet(*tFuncPtr)(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, T));
        public:
            Type(){}
            virtual ~Type()
            {
                this->Clear();
            }
        protected:
            ::Wiz::Void::Type Register(tFunction& F)
            {
                m_Container.Insert(F);
            }
            ::Wiz::Void::Type Unregister(tFunction& F)
            {
                tContainer::tIterator Itr = m_Container.Find(F);
                if (Itr != m_Container.End())
                {
                    m_Container.Erase(Itr);
                }
            }
        public:
            ::Wiz::Void::Type Register(tRet(*FuncPtr)(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, T)))
            {
                Register(tFunction(FuncPtr));
            }
            ::Wiz::Void::Type Unregister(tRet(*FuncPtr)(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, T)))
            {
                Unregister(tFunction(FuncPtr));
            }
            template<class U>
            ::Wiz::Void::Type Register(const U* C, tRet(U::*FP)(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, T)))
            {
                Register(tFunction(C, FP));
            }
            template<class U>
            ::Wiz::Void::Type Unregister(const U* C, tRet(U::*FP)(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, T)))
            {
                Unregister(tFunction(C, FP));
            }
            template<class U>
            ::Wiz::Void::Type Register(U* C)
            {
                Register(tFunction(C));
            }
            template<class U>
            ::Wiz::Void::Type Unregister(U* C)
            {
                Unregister(tFunction(C));
            }
        public:
            ::Wiz::Void::Type operator+=(tFunction& F)
            {
                Register(F);
            }
            ::Wiz::Void::Type operator-=(tFunction& F)
            {
                Unregister(F);
            }
            ::Wiz::Void::Type operator+=(tFuncPtr FuncPtr)
            {
                this->Register(FuncPtr);
            }
            ::Wiz::Void::Type operator-=(tFuncPtr FuncPtr)
            {
                this->Unregister(FuncPtr);
            }
            template<class U>
            ::Wiz::Void::Type operator+=(U* C)
            {
                this->Register(C);
            }
            template<class U>
            ::Wiz::Void::Type operator-=(U* C)
            {
                this->Unregister(C);
            }
        public:
            ::Wiz::Void::Type operator()(WIZ_ENUM_PARAM_XY(WIZ_SIGNAL_PARAM_COUNT, T, A))
            {
                this->SignalExecute(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, A));
            }
        public:
            ::Wiz::Void::Type Clear()
            {
                m_Container.Clear();
            }
        public:
            ::Wiz::Size::Type Size()
            {
                return m_Container.Size();
            }
        public:
            tContainer m_Container;
        protected:
            ::Wiz::Void::Type SignalExecute(WIZ_ENUM_PARAM_XY(WIZ_SIGNAL_PARAM_COUNT, T, A))
            {
                tContainer::tForEachIter  FE(m_Container);
                while (FE)
                {
                    (*FE)(WIZ_ENUM_PARAM_X(WIZ_SIGNAL_PARAM_COUNT, A));
                    FE++;
                }
            }
        };
    } /// end of namespace Signal
} /// end of namespace Wiz


#endif /*WIZ_SIGNAL_PARAM_COUNT*/
